#include "Socket.h"

#include "InetAddress.h"
#include "SocketsOps.h"
#include "../base/logging.h"

#include <netinet/in.h>
#include <netinet/tcp.h>
#include <strings.h>  // bzero

Socket::~Socket()
{
	sockets::close(m_sockfd);
}

void Socket::bindAddress(const InetAddress& localaddr)
{
	sockets::bindOrDie(m_sockfd,localaddr.getSockAddr());
}
	
void Socket::listen()
{
	sockets::listenOrDie(m_sockfd);
}

int Socket::accept(InetAddress* peeraddr)
{
	struct sockaddr_in addr;
	bzero(&addr, sizeof(struct sockaddr_in));
	int connfd = sockets::accept(m_sockfd, &addr);
	peeraddr->setSockAddrInet(addr);
	return connfd;
}

void Socket::setReuseAddr(bool on)
{
	int optval = on ? 1 : 0;
	::setsockopt(m_sockfd, SOL_SOCKET, SO_REUSEADDR, &optval, static_cast<socklen_t>(sizeof optval));
	// FIXME CHECK
}

void Socket::setReusePort(bool on)
{
	int optval = on ? 1 : 0;
	int ret = ::setsockopt(m_sockfd, SOL_SOCKET, SO_REUSEPORT, &optval, static_cast<socklen_t>(sizeof optval));
	if (ret < 0 && on)
	{
		LOG_SYSERR << "SO_REUSEPORT failed.";
	}
}

void Socket::setTcpNoDelay(bool on)
{
	int optval = on ? 1 : 0;
	::setsockopt(m_sockfd, IPPROTO_TCP, TCP_NODELAY,
		&optval, static_cast<socklen_t>(sizeof optval));
	// FIXME CHECK
}

void Socket::shutdownWrite()
{
	sockets::shutdownWrite(m_sockfd);
}